<?php

/**
 * cpd SDK
 * @author chenyun
 */

namespace App\Service\VendorClient\Shopcpd;
use App\Service\Code\Normal;
use App\Service\TaskServer\TaskWorker;
use Service\AppService\IdService;

class ShopcpdApiClient
{
    private $account  = 'Shopcpd';
    protected $config;
    /**
     * 初始参数
     * @param obj $collection
     */
    public function __construct( $apiBody = [] ) 
    {
        $this->config = $apiBody;
    }
    
    /**
     * 创建订单
     */
    public function uploadOrderInfo( $params = [] ) 
    {   
        ini_set('serialize_precision', 16);
        if( empty($params['orderGoods']) || empty($params['supplierOrder']) ) {
            return Normal::returnCode(Normal::FAIL,"except param  orderGoods or supplierOrder");
        }
        //会员编码
        $unionCode        = $params['unionCode'];
        //订单类型：1代表正单，2代表退单
        $orderType        = $params['orderType'];
        //组装订单参数
        $orderInfo = current($params['supplierOrder']);
        //商品下单组
        $productList = [];
        $productAmt   =$TotalCount =$TaxAmt = 0 ;
        foreach ($params['orderGoods'] as $key => $item ) 
        {
            //卖价
            $price              = $item['price'];
            //商品购买规格数量
            $spec_num           = $item['spec_num'];
            //商品购买数量(下单数量 X 起售数量)
            $quantity           = $item['quantity'];
            //实际购买数量
            $buyAcount          = $spec_num * $quantity ;
            //单个商品价格
            $singleGoodsPrice   = bcdiv((string)$price, (string)$spec_num,3);
            $singleGoodsPrice   = ceil(bcmul((string)$singleGoodsPrice,(string)'100',1));
            $singleGoodsPrice   = bcdiv((string)$singleGoodsPrice,'100',2);
            //单个商品总不含税价格
            $totalGoods     = bcmul((string)$singleGoodsPrice,(string)$buyAcount,2);
            //商品组
            $productList[] = [
                "commodityCode"     => $item['supplier_skucode'],
                "commodityName"     => $item['goods_name'],
                "color"             => "",
                "spec"              => "",
                "price"             =>(float)$singleGoodsPrice,
                "discountPrice"     => 0.00,
                "quant"             => $buyAcount,
                "amt"               => (float)$totalGoods,
                "originalOrderId"   => $orderType == 2 ? $orderInfo['supplier_dsn'] : '',
                "skuSuiteId"        => "",
                "type"              => "YFG",
                "posterSkuId"       => "",
                "liveRoom"          => "",
            ];
            $TotalCount = bcadd($TotalCount,$buyAcount);
            $productAmt = bcadd((string)$productAmt,(string)$totalGoods,2);
        }
        //运费
        $deliver_money  = 0;
        
        //实际下单金额 
        $real_total_money = $orderInfo['real_total_money'];
        
        //订单总金额 = 不含税商品总金额 + 总税费 + 运费 - 优惠金额
        $ActualPaidAmt  = bcadd((string)$productAmt,(string)$TaxAmt,2);
        $ActualPaidAmt  = bcadd((string)$ActualPaidAmt,(string)$deliver_money,2);
        
        //优惠金额
        $discount_money = bcsub((string)$ActualPaidAmt,$real_total_money,2);
        
        $payTime        = $orderInfo['pay_time'];
        $pay_time       = $payTime ? $payTime : time();
        //下单时间，如果下单时间晚于支付时间，就传支付时间，否则传下单时间
        $tradeTime      = $orderInfo['cd'] > $pay_time ? $pay_time : $orderInfo['cd'];

        //支付时间
        $pay_time       = date('Y-m-d H:i:s',$payTime);   
        
        $data = [
            'brand_code'        => $this->config['brand_code'],//品牌标识
            'program_code'      => $this->config['program_code'],//俱乐部编号
            'storeCode'         => $this->config['store_code'],//门店编码
            'union_code'        => $unionCode,//会员编码
            'channelMemberId'   => $unionCode,
            'channelType'       => "union_code",
            'tmallOuid'         => "",
            'card_no'           => $unionCode,
            'orderType'         => $orderType,
            'orderSellType'     => 'fixed',
            'tradeNo'           => $orderType == 2 ? "AF".$orderInfo['supplier_dsn'] : $orderInfo['supplier_dsn'],
            'tradeTime'         => date('Y-m-d H:i:s', $tradeTime), 
            'TotalCount'        => $TotalCount,
            'Paymenttime'       => $pay_time,
            'TotalPrice'        => (float)$ActualPaidAmt,
            'tradePrice'        => (float)$real_total_money,
            'earnestAmount'     => 0.00,
            'basicPricceUsed'   => 0.00,
            'expandPriceUsed'   => 0.00,
            'discountPrice'     => (float)$discount_money,
            'postAmount'        => (float)$deliver_money,
            'couponCode'        => "",
            'campaignCode'      => "",
            'employeeCode'      => "",
            'employeeName'      => "",
            'store_name'        => "",
            'remark'            => $orderInfo['order_remark'],
            'productList'       => $productList,
            'logistics'         => [
                    "Buyer_name"        => $orderInfo['receive_name'],
                    "Buyer_mobile"      => $orderInfo['recveive_phone'],
                    "provinceCode"      => "",
                    "provinceName"      => $orderInfo['province'],
                    "cityCode"          => "",
                    "cityName"          => $orderInfo['city'],
                    "countryCode"       => "",
                    "countr  yName"     => $orderInfo['district'],
                    "adress"            => $orderInfo['receive_address'],
                    "status"            => "",
                    "earnestAmount"     => 0.00,
            ],
            'itemPacks'          => [
                    "packCode"          => "",
                    "itemQty"           => 0,
                    "itemSku"           => "",
                    "orderQty"          => 0,
            ],
            'promotionList'     => [
                    "promotionId"       => "",
                    "promotionName"     => "",
                    "promotionDesc"     => "",
                    "promotionId"       => "",
                    "discountFee"       => 0.00,
                    "itemName"          => "",
                    "itemSku"           => "",
                    "itemQty"           => 0,
                    "storeCode"         => "",
                    "sourceId"          => "",
            ],
            'payList'           => [
                    "payCode"           => "",
                    "payName"           => "",
                    "payAmt"            => "",
            ],
            'orderExtend'       => [
                    "subscribeOrderFlag"=> "",
                    "thirdStoreName"    => "",
                    "hasGoodReturn"     => "",
            ]
        ];
        $requestParam = [
            'method'    => 'uploadOrderInfo',
            'ruid'      => $params["ruid"],
            'data'      => $data
        ];
        return $this->execute($requestParam);
    }
    
    /**
     * 获取取消订单
     */
    public function updateOrderStatus($params = []) 
    {
        $data = [
            'brand_code'        => $this->config['brand_code'],//品牌标识
            'program_code'      => $this->config['program_code'],//俱乐部编号
            'order_no'          => $params["orderSn"],
            'status'            => $params["status"],
            'storeCode'         => $this->config['store_code'],//门店编码
        ];
        $requestParam = [
            'method'    => 'updateOrderStatus',
            'ruid'      => $params["ruid"],
            'data'      => $data
        ];
        return $this->execute($requestParam);
    }
    /**
     * 查询会员信息
     */
    public function queryMember( $params = [] )
    {
        $data = [
            'brand_code'    => $this->config["brand_code"],
            'program_code'  => $this->config["program_code"],
            'queryType'     => 'mobile',
            'Value'         => $params["mobile"],
        ];
        $requestParam = [
            'method'    => 'queryMember',
            'ruid'      => $params["ruid"],
            'data'      => $data
        ];
        return $this->userExecute($requestParam);
    }

    /**
     * 注册绑定会员信息
     */
    public function userRegister( $params = [] )
    {
        $media_account[]=[
            'type'            => '3',
            'accountNo'       => $params["accountNo"],
            'nickname'        => $params["nickname"],
            'fromSocialCode'  => $this->config["fromSocialCode"],
            'remark'          => "",
            'status'          => "0",
            'bindDate'        => date("Y-m-d H:i:s",time()),
            'consentStatus'   => "0",
            'consentTime'     => date("Y-m-d H:i:s",time()),
            'unionId'         => "0",
            'bindEmployee'    => "",
            'bindStore'       => $this->config["store_code"],
        ];
        $data = [
            'brand_code'    => $this->config["brand_code"],
            'program_code'  => $this->config["program_code"],
            'mobile'        => $params["mobile"],
            'chanel_code'   => $this->config["chanel_code"],
            'consentStatus' => "0",
            'consentTime'   => date("Y-m-d H:i:s",time()),
            'consentVersion'=> $this->config["consentVersion"],
            'store_code'    => $this->config["store_code"],
            'Media_account' => $media_account,
        ];
        $requestParam = [
            'method'    => 'userRegister',
            'ruid'      => $params["ruid"],
            'data'      => $data
        ];
        return $this->userExecute($requestParam);
    }
    /**
     * 查询会员等级
     */
    public function queryMemberGrade( $params = [] )
    {
        $data = [
            'brand_code'    => $this->config["brand_code"],
            'program_code'  => $this->config["program_code"],
            'queryType'     => $params["queryType"],
            'value'         => $params["value"],
        ];
        $requestParam = [
            'method'    => 'queryMemberGrade',
            'ruid'      => $params["ruid"],
            'data'      => $data
        ];
        return $this->userExecute($requestParam);
    }
    /**
     * 查询会员积分
     */
    public function queryMemberPoints( $params = [] )
    {
        $data = [
            'brand_code'    => $this->config["brand_code"],
            'program_code'  => $this->config["program_code"],
            'queryType'     => $params["queryType"],
            'value'         => $params["value"],
        ];
        $requestParam = [
            'method'    => 'queryMemberPoints',
            'ruid'      => $params["ruid"],
            'data'      => $data
        ];
        return $this->userExecute($requestParam);
    }
    /**
     * 查询会员距离下一个等级还需要消费多少
     */
    public function queryMemberGradeCalculator( $params = [] )
    {
        $data = [
            'brand_code'    => $this->config["brand_code"],
            'program_code'  => $this->config["program_code"],
            'queryType'     => $params["queryType"],
            'value'         => $params["value"],
            'grade'         => $params["grade"],
            'upGrade'       => $params["upGrade"],
        ];
        $requestParam = [
            'method'    => 'queryMemberGradeCalculator',
            'ruid'      => $params["ruid"],
            'data'      => $data
        ];
        return $this->userExecute($requestParam);
    }
    /**
     * 等级定义查询
     */
    public function queryTierList( $params = [] )
    {
        $data = [
            'brand_code'    => $this->config["brand_code"],
            'program_code'  => $this->config["program_code"],
        ];
        $requestParam = [
            'method'    => 'queryTierList',
            'ruid'      => $params["ruid"],
            'data'      => $data
        ];
        return $this->userExecute($requestParam);
    }
    /**
     * 完善会员信息
     */
    public function improveMemberInfo( $params = [] )
    {
        $data = [
            'brand_code'    => $this->config["brand_code"],
            'program_code'  => $this->config["program_code"],
            'acct_type'     => "0",
            'acct_cd'       => "",
            'acct_no'       => "",
            'tmall_ouid'    => "",
            'acct_nm'       => $params["mobile"],
            'name'          => $params["name"] ?? "",
            'mobile'        => $params["mobile"],
            'birthday'      => $params["birthday"] ?? "",
        ];
        $requestParam = [
            'method'    => 'improveMemberInfo',
            'ruid'      => $params["ruid"],
            'data'      => $data
        ];
        return $this->userExecute($requestParam);
    }
    /**
     * 会员积分变更接口
     */
    public function changeMemberPoints( $params = [] )
    {
        $data = [
            'brand_code'        => $this->config["brand_code"],
            'program_code'      => $this->config["program_code"],
            'queryType'         => $params["queryType"],
            'value'             => $params["value"],
            'pointType'         => $params["pointType"],
            'points'            => $params["points"],
            'changeType'        => $params["changeType"],
            'changeSouce'       => $params["changeSouce"],
            'vender_seq_code'   => $params["vender_seq_code"],
            'remark'            => $params["remark"],
            'vender_code'       => $this->config["vender_code"],
        ];
        $requestParam = [
            'method'    => 'changeMemberPoints',
            'ruid'      => $params["ruid"],
            'data'      => $data
        ];
        return $this->userExecute($requestParam);
    }
    /**
     * 会员积分变更状态查询接口
     */
    public function queryMemberPointChangeStatus( $params = [] )
    {
        $data = [
            'brand_code'        => $this->config["brand_code"],
            'program_code'      => $this->config["program_code"],
            'vender_seq_code'   => $params["vender_seq_code"],
            'vender_code'       => $this->config["vender_code"],
            'queryType'         => $params["queryType"],
            'value'             => $params["value"],
        ];
        $requestParam = [
            'method'    => 'queryMemberPointChangeStatus',
            'ruid'      => $params["ruid"],
            'data'      => $data
        ];
        return $this->userExecute($requestParam);
    }
    
    /**
     * 上传兑换信息(新)接口
     */
    public function submitGiftInfo( $params = [] )
    {
        //组装订单参数
        $orderInfo = current($params['supplierOrder']);
        $productList =[];
        foreach ($params['orderGoods'] as $key => $item )
        {
            //商品购买规格数量
            $spec_num           = $item['spec_num'];
            //商品购买数量(下单数量 X 起售数量)
            $quantity           = $item['quantity'];
            //实际购买数量
            $buyAcount          = $spec_num * $quantity ;
            //商品组
            $productList[] = [
                "commodityCode"     => $item['supplier_skucode'],
                "commodityName"     => $item['goods_name'],
                "commodityType"     => "P",
                "Points"            => $params["totalPoints"],
                "discountPoints"    => 0,
                "quant"             => $buyAcount,
                "amt"               => $params["totalPoints"],
                "originalTradeNo"   => $params["orderType"] == 2 ? $params["orderSn"] :"",
            ];
        }
        $data = [
            'brand_code'        => $this->config["brand_code"],
            'program_code'      => $this->config["program_code"],
            'vender_seq_code'   => $params["vender_seq_code"],
            'vender_code'       => $this->config["vender_code"],
            'queryType'         => $params["queryType"],
            'value'             => $params["value"],
            'tradeNo'           => $params["orderType"] == 2 ? "T".$params["orderSn"] :$params["orderSn"],
            'orderType'         => $params["orderType"],
            'tradeTime'         => date("Y-m-d H:i:s",$orderInfo["cd"]),
            'TotalCount'        => 0,
            'totalPoints'       => $params["totalPoints"],
            'Paymenttime'       => date("Y-m-d H:i:s",$orderInfo["pay_time"]),
            'Chanel_code'       => $this->config["Chanel_code"],
            'productList'       => $productList,
        ];
        $requestParam = [
            'method'    => 'submitGiftInfo',
            'ruid'      => $params["ruid"],
            'data'      => $data
        ];
        return $this->userExecute($requestParam);
    }
    
    /**
     * 综合查询接口
     */
    public function info( $params = [] )
    {
        $data = [
            'brand_code'    => $this->config["brand_code"],
            'program_code'  => $this->config["program_code"],
            'ruid'          => $params["requestRuid"],
        ];
        $requestParam = [
            'method'    => 'info',
            'ruid'      => $params["ruid"],
            'data'      => $data
        ];
        return $this->userExecute($requestParam);
    }
    
    /**
     * 获取token
     * @param array $param
     */
    protected function getToken( array $param = [] )
    {
        $redis= redis();
        $cacheKey    = $this->account."TokenKey";
        $AccessToken = $redis->get($cacheKey);
        if(empty($AccessToken)){
            //获取用户token
            $userLoginData = [
                'grant_type'    => 'password',
                'username'      => $this->config["username"],
                'password'      => $this->config["password"]
            ];
            $requestParam = [
                'method'    => 'getToken',
                'data'      => $userLoginData
            ];
            $res= $this->tokenExecute($requestParam);
            if($res["code"]== Normal::SUC){
                $AccessToken=$res["data"]["access_token"];
                //定时刷新token（20分钟）
                $redis->set($cacheKey,$AccessToken,60*20);
                return Normal::returnCode(Normal::SUC,"获取成功",$AccessToken);
            }
            return $res;
        }
        return Normal::returnCode(Normal::SUC,"获取成功",$AccessToken);
    }
    
    /**
     * CURL请求
     * @param $params
     * @return mixed
     */
    public function execute( $param = [] )  
    {
        if( empty($param['data']) ) {
            return Normal::returnCode(Normal::FAIL,"数据不能为空");
        }
        $method=$param["method"];
        $url = $this->config['baseurl'].$this->config[$method];
        $tokenRes=$this->getToken();
        if($tokenRes["code"] != Normal::SUC){
            return Normal::returnCode(Normal::SUC,$res["msg"]);
        }
        $token=$tokenRes["data"];
        $uuid = uniqid('ruid');
        if(isset($param["ruid"])){
            $uuid = $param["ruid"];
        }
        $parameter = [
            [
                'tag'       => $this->account.'_'.$method,
                'uid'       => IdService::instance()->getOtherID(),
                'url'       => $url,
                'data'      => $param['data'],
                'method'    => 'post',
                'format'    => 'json',
                'header'    => [
                    "ruid:{'uuid':'{$uuid}'}",
                    'Content-Type:application/json;charset=utf-8',
                    "Authorization:Bearer {$token}",
                ],
            ],
        ];
        $resTask = TaskWorker::instance()->addTask($parameter);
        $resTask = current($resTask);
        $res     = $resTask['response']['result'];
        $resHttp = json_decode($res,true);
        if( isset($resHttp['code']) && $resHttp['code'] == 0 ) {
            return Normal::returnCode(Normal::SUC,"操作成功");
        }
        $message = isset($resHttp['error_description']) ? $resHttp["error_description"] : '请求失败';
        return Normal::returnCode(Normal::FAIL,$message);
    }
    /**
     * CURL请求
     * @param $params
     * @return mixed
     */
    public function tokenExecute( $param = [] )
    {
        $method=$param["method"];
        $url = $this->config['baseurl'].$this->config[$method];
        $uuid = uniqid('ruid');
        $token=base64_encode($this->config["client_id"].":".$this->config["client_secret"]);
        $parameter = [
            [
                'tag'       => $this->account.'_'.$method,
                'uid'       => IdService::instance()->getOtherID(),
                'url'       => $url,
                'data'      => $param['data'],
                'method'    => 'post',
                'format'    => 'form-data',
                'header'    => [
                    "Authorization: Basic {$token}",
                 ],
              ],
       ];
        $resTask = TaskWorker::instance()->addTask($parameter);
        $resTask = current($resTask);
        $res     = $resTask['response']['result'];
        $resHttp = json_decode($res,true);
        if( isset($resHttp) && isset($resHttp['access_token'])) {
            return Normal::returnCode(Normal::SUC,"操作成功",$resHttp);
        }
        $message = isset($resHttp['error_description']) ? $resHttp["error_description"] : '请求失败';
        return Normal::returnCode(Normal::FAIL,$message);
    }
    /**
     * CURL请求
     * @param $params
     * @return mixed
     */
    public function userExecute( $param = [] )
    {
        if( empty($param['data']) ) {
            return Normal::returnCode(Normal::FAIL,"数据不能为空");
        }
        $method  = $param["method"];
        $url     = $this->config['baseurl'].$this->config[$method];
        $result_token = $this->getToken();
        if( $result_token["code"] != Normal::SUC){
            return Normal::returnCode(Normal::FAIL,"获取LRP会员中心token失败【{$result_token["msg"]}】",$result_token);
        }
        
        $token  = $result_token["data"];
        $uuid   = uniqid('ruid');
        if(isset($param["ruid"])){
            $uuid = $param["ruid"];
        }
        $parameter = [
            [
                'tag'       => $this->account.'_'.$method,
                'uid'       => IdService::instance()->getOtherID(),
                'url'       => $url,
                'data'      => $param['data'],
                'method'    => 'post',
                'format'    => 'json',
                'header'    => [
                    "ruid:{'uuid':'{$uuid}'}",
                    'Content-Type:application/json;charset=utf-8',
                    "Authorization:Bearer {$token}",
                 ],
              ],
        ];
        $resTask = TaskWorker::instance()->addTask($parameter);
        $resTask = current($resTask);
        $res     = $resTask['response']['result'];
        $resHttp = json_decode($res,true);
        if( isset($resHttp['code']) && $resHttp['code'] == 0 ) {
            $data = isset($resHttp["data"])? $resHttp["data"] : [];
            return Normal::returnCode(Normal::SUC,"操作成功",$data);
        }
        $message = isset($resHttp['msg']) ? $resHttp["msg"] : '请求失败';
        return Normal::returnCode(Normal::FAIL,$message);
    }
}